# Copyright 2008 Brooklyn Marathon Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

__author__ = 'r.yozzo (Ralph Yozzo)'

import logging
# to test email:
from google.appengine.api import mail
# if not mail.is_email_valid(to_addr):


import os

from base64 import b64encode

from google.appengine.api import users

from google.appengine.ext import db
from google.appengine.ext.db import djangoforms
from google.appengine.api import urlfetch

import django
from django import http
from django import shortcuts
import urllib
from string import split

#from forms import BaseForm, DeclarativeFieldsMetaclass, SortedDictFromList

# Import the main gchecky controller class
from gchecky.controller import Controller
from xml.dom import minidom
from django.views.generic.simple import redirect_to

import datetime

class Race(db.Model):

  name = db.StringProperty(required=True,default='race name')
  #date = db.DateProperty(required=True,default='yyyy-mm-dd',help_text='Format is yyyy-mm-dd')
  date = db.DateProperty(required=True,default='yyyy-mm-dd')
  time = db.TimeProperty(required=True,default='hh:mm')
  location = db.StringProperty(required=True)
  distance_in_miles = db.FloatProperty(required=True)

#  race = db.StringProperty(required=True,default='2009 Boston Marathon',choices=['2009 Boston Marathon', '2008 Prospect Park Cherry Tree 10 Miler', 'Prospect Park Duathlon & Gotham Cup Club Challenge Sunday, November 9, 2008' ])
#  first = db.StringProperty(required=True)
#  last = db.StringProperty(required=True)
#  age = db.IntegerProperty(required=True,default=20,choices=[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
#  gender = db.StringProperty(required=True,default='M',choices=['M','F'])
#  division = db.StringProperty(required=True,default='Open',choices=['Open', 'Clydesdale', 'Athena' ])
  racedirector = db.UserProperty()
  payment_company = db.StringProperty(required=True,default='Google Checkout',choices=['Google Checkout', 'Paypal' ])
  payment_company_id = db.StringProperty(required=True)
  payment_company_key = db.StringProperty(required=True)
  #is_sandbox = db.BooleanProperty(required=False, default='False')
  early_registration_deadline_date = db.DateProperty(required=True,default='yyyy-mm-dd');
  early_registration_member_price = db.FloatProperty(required=True)
  early_registration_nonmember_price = db.FloatProperty(required=True)
  late_registration_member_price = db.FloatProperty(required=True)
  late_registration_nonmember_price = db.FloatProperty(required=True)
  race_day_price = db.FloatProperty(required=True)
  payment_cost = db.FloatProperty(required=False)
  nonprofit = db.BooleanProperty(required=False)
  website = db.StringProperty()
  registration_closing_date = db.DateProperty(required=True,default='yyyy-mm-dd')
  registration_closing_time = db.TimeProperty(required=True,default='hh:mm')
  brief_description = db.StringProperty()
  full_description = db.TextProperty()
  brief_message_to_buyer_about_delivery = db.StringProperty(required=True)
  early_packet_pickup = db.TextProperty()
  race_day_packet_pickup = db.TextProperty()
  souvenirs = db.TextProperty()
  course = db.TextProperty()
  timing = db.TextProperty()
  awards = db.TextProperty()
  post_race_refreshments = db.TextProperty()
  baggage_check = db.TextProperty()
  travel_directions = db.TextProperty()
  comments = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()

class Entry(db.Model):

  first = db.StringProperty(required=True)
  last = db.StringProperty(required=True)
  age = db.IntegerProperty(required=True,default=20,choices=[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
  gender = db.StringProperty(required=True,default='M',choices=['M','F'])
  shirt_size = db.StringProperty(default='Medium',choices=['Small', 'Medium', 'Large', 'XL' ])
  division = db.StringProperty(required=True,default='Open',choices=['Open', 'Clydesdale', 'Athena' ])
  racedirector = db.UserProperty()
  comments = db.TextProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()
  raceid = db.IntegerProperty()

class Club(db.Model):
  club_contact_person_name = db.StringProperty(required=False)
  email = db.StringProperty(required=True)
  name = db.StringProperty(required=True)
  location = db.StringProperty(required=True)
  payment_company = db.StringProperty(required=True,default='Google Checkout',choices=['Google Checkout', 'Paypal' ])
  payment_company_id = db.StringProperty(required=True)
  payment_company_key = db.StringProperty(required=True)
  payment_mode = db.StringProperty(required=False,default='Production',choices=['Production', 'Test' ])
  one_year_individual_member_price = db.FloatProperty(required=True)
  one_year_household_member_price = db.FloatProperty(required=True)
  five_year_individual_member_price = db.FloatProperty(required=True)
  five_year_household_member_price = db.FloatProperty(required=True)
  advertisement = db.StringProperty(required=False)
  website = db.LinkProperty(required=True)
  brief_description = db.StringProperty()
  full_description = db.TextProperty()
  brief_message_to_buyer_about_delivery = db.StringProperty(required=True)
  racedirector = db.UserProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()
  #question1_type = db.StringProperty(default='Text',choices=['Text', 'Choices' ])
  #question1_text = db.StringProperty()
  #question1_choices = db.StringProperty()

class ClubForm(djangoforms.ModelForm):
  def __init__(self, *args, **kwargs):
    super(ClubForm, self).__init__(*args, **kwargs)
    self.fields.get("email").help_text='Your club contact email address'
    self.fields.get("name").help_text='The name of your club'
  class Meta:
    model = Club
    exclude = ['racedirector', 'created', 'modified', 'ip']

# class DynamicStringProperty(db.StringProperty):
#   def get_value_for_form(self, instance):
# 	#print 'XXX'
#     return getattr(instance, self.name)

class ClubEntry(db.Model):

  membership_type = db.StringProperty(required=True,choices=[ 'One year individual member price', 'One year household member price', 'Five year individual member price', 'Five year household member price'] )
  first = db.StringProperty(required=True)
  middle = db.StringProperty(required=False)
  last = db.StringProperty(required=True)
  gender = db.StringProperty(required=True,choices=['M','F'])
  #age = db.IntegerProperty(required=True,default=20,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
  birth_month = db.IntegerProperty(required=True,choices=[1,2,3,4,5,6,7,8,9,10,11,12])
  birth_day = db.IntegerProperty(required=True,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])
  birth_year = db.IntegerProperty(required=True,default=1970,choices=[
1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000
      ])
  email = db.StringProperty(required=True)
  #email2 = db.StringProperty(required=True)
  daytime_phone_number = db.StringProperty(required=True)
  evening_phone_number = db.StringProperty(required=False)
  address_line_1 = db.TextProperty(required=True)
  address_line_2 = db.TextProperty(required=False)
  city = db.StringProperty(required=True)
  state = db.StringProperty(required=True,default='New York',choices=[
    'Alabama',       'Alaska',              'American Samoa', 'Arizona',
    'Arkansas',      'California',          'Colorado',       'Connecticut',
    'Delaware',      'District of Columbia','Florida',        'Georgia',
    'Guam',          'Hawaii',              'Idaho',          'Illinois',
    'Indiana',       'Iowa',                'Kansas',         'Kentucky',
    'Louisiana',     'Maine',               'Maryland',       'Massachusetts',
    'Michigan',      'Minnesota',           'Mississippi',    'Missouri',
    'Montana',       'Nebraska',            'Nevada',         'New Hampshire',
    'New Jersey',    'New Mexico',          'New York',       'North Carolina',
    'North Dakota',  'Ohio',                'Oklahoma',       'Oregon',
    'Pennsylvania',  'Puerto Rico',         'Rhode Island',   'South Carolina',
    'South Dakota',  'Tennessee',           'Texas',          'Utah',
    'Vermont',       'Virgin Islands',      'Virginia',       'Washington',
    'West Virginia', 'Wisconsin',           'Wyoming'
      ])

#  country = db.StringProperty(required=True)

  country = db.StringProperty(required=True,default='United States',choices=[
   'Afghanistan',
    'Albania',
    'Algeria',
    'American Samoa', #dependent
    'Andorra',
    'Angola',
    'Anguilla', #dependent
#    'Antarctica',
    'Antigua and Barbuda',
    'Argentina',
    'Armenia',
    'Aruba', #dependent
    'Australia',
    'Austria',
    'Azerbaijan',
    'Bahamas',
    'Bahrain',
    'Bangladesh',
    'Barbados',
    'Belarus',
    'Belgium',
    'Belize',
    'Benin',
    'Bermuda', #dependent
    'Bhutan',
    'Bolivia',
    'Bosnia and Herzegovina',
    'Botswana',
#    'Bouvet Island',
    'Brazil',
    'British Indian Ocean Territory',
    'Brunei Darussalam',
    'Bulgaria',
    'Burkina Faso',
    'Burundi',
    'Cambodia',
    'Cameroon',
    'Canada',
    'Cape Verde',
    'Cayman Islands', #dependent
    'Central African Republic',
    'Chad',
    'Chile',
    'China (*',
    'Christmas Island', #dependent
    'Cocos (Keeling) Islands', #dependent
    'Colombia',
    'Comoros',
    'Congo (*',
    'Cook Islands', #dependent
    'Costa Rica',
    'Croatia',
    'Cuba',
    'Cyprus',
    'Czech Republic',
    'Denmark',
    'Djibouti',
    'Dominica',
    'Dominican Republic',
    'East Timor',
    'Ecuador',
    'Egypt',
    'El Salvador',
    'Equatorial Guinea',
    'Eritrea',
    'Estonia',
    'Ethiopia',
    'Falkland Islands (Malvinas)', #dependent
    'Faroe Islands',
    'Fiji',
    'Finland',
    'France',
    'French Guiana',
    'French Polynesia', #dependent
    'French Southern Territories',
    'Gabon',
    'Gambia',
    'Georgia',
    'Germany',
    'Ghana',
    'Gibraltar', #dependent
    'Greece',
    'Greenland',
    'Grenada',
    'Guadeloupe',
    'Guam', #dependent
    'Guatemala',
    'Guernsey', #dependent
    'Guinea',
    'Guinea-Bissau',
    'Guyana',
    'Haiti',
    'Heard and Mc Donald Islands',
    'Honduras',
    'Hong Kong', #special
    'Hungary',
    'Iceland',
    'India',
    'Indonesia',
    'Iran (*',
    'Iraq',
    'Ireland',
    'Isle of Man', #dependent
    'Israel',
    'Italy',
    'Jamaica',
    'Japan',
    'Jersey', #dependent
    'Jordan',
    'Kazakhstan',
    'Kenya',
    'Kiribati',
    'Kosovo', #UN protectorate
    'North Korea',
    'South Korea',
    'Kuwait',
    'Kyrgyzstan',
    'Laos',
    'Latvia',
    'Lebanon',
    'Lesotho',
    'Liberia',
    'Libya',
    'Liechtenstein',
    'Lithuania',
    'Luxembourg',
    'Macau', #special
    'Macedonia',
    'Madagascar',
    'Malawi',
    'Malaysia',
    'Maldives',
    'Mali',
    'Malta',
    'Marshall Islands',
    'Martinique',
    'Mauritania',
    'Mauritius',
    'Mayotte', #dependent
    'Mexico',
    'Micronesia',
    'Moldova',
    'Monaco',
    'Mongolia',
    'Montserrat', #dependent
    'Morocco',
    'Mozambique',
    'Myanmar',
    'Namibia',
    'Nauru',
    'Nepal',
    'Netherlands',
    'Netherlands Antilles', #dependent
    'New Caledonia', # dependent
    'New Zealand',
    'Nicaragua',
    'Niger',
    'Nigeria (*',
    'Niue', #dependent
    'Norfolk Island', #dependent
    'Northern Mariana Islands', #dependent
    'Norway',
    'Oman',
    'Pakistan (*',
    'Palau',
    'Palestine', #non-de-facto
    'Panama',
    'Papua New Guinea',
    'Paraguay',
    'Peru',
    'Philippines',
    'Pitcairn Islands', #dependent
    'Poland',
    'Portugal',
    'Puerto Rico', #dependent
    'Qatar',
    'Reunion',
    'Romania',
    'Russia',
    'Rwanda',
    'Saint Kitts and Nevis',
    'Saint Helena', #dependent
    'Saint Lucia',
    'Saint Pierre and Miquelon', #dependent
    'Saint Vincent and the Grenadines',
    'Samoa',
    'San Marino',
    'Saudi Arabia',
    'Senegal',
    'Serbia and Montenegro',
    'Seychelles',
    'Sierra Leone',
    'Singapore',
    'Slovakia',
    'Slovenia',
    'Solomon Islands',
    'Somalia',
    'South Africa',
#    'South Georgia and The South Sandwich Islands',
    'Spain',
    'Sri Lanka',
    'Sudan',
    'Suriname',
    'Svalbard', #special
    'Swaziland',
    'Sweden',
    'Switzerland',
    'Syria',
    'Taiwan, Province Of China',
    'Tajikistan',
    'Tanzania',
    'Thailand',
    'East Timor',
    'Togo',
    'Tokelau', #dependent
    'Tonga',
    'Trinidad and Tobago',
    'Tunisia',
    'Turkey',
    'Turkmenistan',
    'Turks and Caicos Islands', #dependent
    'Tuvalu',
    'Uganda',
    'Ukraine',
    'United Arab Emirates',
    'United Kingdom',
    'United States',
    'United States Minor Outlying Islands',
    'Uruguay',
    'Uzbekistan',
    'Vanuatu',
    'Vatican City State (Holy See)',
    'Venezuela',
    'Viet Nam',
    'Virgin Islands (British)', #dependent
    'Virgin Islands (U.S.)', #dependent
    'Wallis and Futuna', #dependent
    'Western Sahara', #non-de-facto
    'Yemen',
    'Zaire',
    'Zambia',
    'Zimbabwe'])


  zipcode = db.StringProperty(required=True)
  #electronic_newsletter = db.BooleanProperty(default=True, verbose_name='Uncheck this box if you want it sent via the Post Office')
  electronic_newsletter = db.BooleanProperty(default=True)
  mailing_list = db.BooleanProperty(default=True)
  how_did_you_hear_about_the_club = db.TextProperty(required=False)
  member_type = db.StringProperty(required=False,default='Runner',choices=['Runner', 'Walker'])
  list_other_club_memberships = db.TextProperty(required=False)
  list_name_in_club_directory = db.BooleanProperty(default=True)
  names_genders_and_birthdays_of_all_of_the_members_of_the_household = db.TextProperty(required=False, verbose_name='Names, genders and birthdays of all of the members of the household')
  #shirt_size = db.StringProperty(default='Medium',choices=['Small', 'Medium', 'Large', 'XL' ])
  #division = db.StringProperty(required=True,default='Open',choices=['Open', 'Clydesdale', 'Athena' ])
  racedirector = db.UserProperty()
  coupon_code = db.StringProperty()
  comments = db.TextProperty()
  checkout_id = db.StringProperty(required=False)
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()
  clubid = db.IntegerProperty()
  ## WORKS
  #dynamic_field1 = db.StringProperty()
  ##
  #dynamic_field1 = DynamicStringProperty()
  #question1 = db.ReferenceProperty()


class RaceForm(djangoforms.ModelForm):
  def __init__(self, *args, **kwargs):
    super(RaceForm, self).__init__(*args, **kwargs)
    user = users.GetCurrentUser()
    # debug
    #user = 'ben1184@gmail.com';
    self.fields.get("date").help_text='Format is yyyy-mm-dd'
    if user is None:
      self.fields.get("first").initial='please sign in.'
#     else:
#       q = db.GqlQuery('SELECT * FROM Race WHERE racedirector = :1 ORDER BY created DESC LIMIT 1', user)
#       if q: 
#         results = q.fetch(1)
#         for result in results:
#       	  self.fields.get("name").initial=result.name
#           self.fields.get("date").initial=result.date
#           self.fields.get("time").initial=result.time
#           self.fields.get("location").initial=result.location
#           self.fields.get("distance_in_miles").initial=result.distance_in_miles
#           self.fields.get("payment_company").initial=result.payment_company
#           self.fields.get("payment_company_id").initial=result.payment_company_id
#           self.fields.get("early_registration_deadline_date").initial=result.early_registration_deadline_date
#           self.fields.get("early_registration_member_price").initial=result.early_registration_member_price
#           self.fields.get("early_registration_nonmember_price").initial=result.early_registration_nonmember_price
#           self.fields.get("late_registration_member_price").initial=result.late_registration_member_price
#           self.fields.get("late_registration_nonmember_price").initial=result.late_registration_nonmember_price
#           self.fields.get("race_day_price").initial=result.race_day_price
  class Meta:
    model = Race
    exclude = ['racedirector', 'created', 'modified', 'ip', 'payment_cost']

#def dyn_form(model, form=BaseForm)
#  return type('XForm', (form,), {'base_fields': {'hi1', 'h2'}, '_model': model}


#class ClubEntryForm(djangoforms.ModelForm):
#  dyn_form(ClubEntry)

class ClubEntryForm(djangoforms.ModelForm):
  #def __init__(self, club, *args, **kwargs):
  def __init__(self, *args, **kwargs):
    super(ClubEntryForm, self).__init__(*args, **kwargs)
    user = users.GetCurrentUser()
    #self.fields.get["membership_type"].append('XXX')
	#self.fields.add("questionX")
	#self.fields.xxx = db.StringProperty()
    #self.fields.get("dynamic_field1").name='xxx'
    #self.fields.get("dynamic_field1").label='yyy'
	## WORKS
    #self.fields.get("dynamic_field1").label=club.question1_text
	##
    #self.fields.get("dynamic_field1").initial='xxx'
    self.fields.get("names_genders_and_birthdays_of_all_of_the_members_of_the_household").help_text='Households only'
    self.fields.get("list_name_in_club_directory").help_text='Uncheck this box if you do not want to be in the club directory. The directory is only distributed to other club members'
    self.fields.get("electronic_newsletter").help_text='Uncheck this box if you want it sent via the post office'
    self.fields.get("mailing_list").help_text = 'Check this box if want to subscribe to the club mailing list'
  class Meta:
    model = ClubEntry
    exclude = ['racedirector', 'created', 'modified', 'ip', 'clubid', 'checkout_id']


class EntryForm(djangoforms.ModelForm):
  class Meta:
    model = Entry
    exclude = ['racedirector', 'created', 'modified', 'ip', 'raceid']
    #exclude = ['racedirector', 'created', 'modified', 'ip']

def respond(request, user, template, params=None):
  """Helper to render a response, passing standard stuff to the response.

  Args:
    request: The request object.
    user: The User object representing the current user; or None if nobody
      is logged in.
    template: The template name; '.html' is appended automatically.
    params: A dict giving the template parameters; modified in-place.

  Returns:
    Whatever render_to_response(template, params) returns.

  Raises:
    Whatever render_to_response(template, params) raises.
  """
  if params is None:
    params = {}
  #questions = ['what is your shoe size?']
  #params['questions'] = questions
  if user:
    params['user'] = user
    params['sign_out'] = users.CreateLogoutURL('/')
    params['is_admin'] = (users.IsCurrentUserAdmin() and 'Dev' in os.getenv('SERVER_SOFTWARE'))
  else:
    params['sign_in'] = users.CreateLoginURL(request.path)
  if not template.endswith('.html'):
    template += '.html'
  return shortcuts.render_to_response(template, params)


def index(request):
  """Request / -- show all races."""

  user = users.GetCurrentUser()
  races = db.GqlQuery('SELECT * FROM Race ORDER BY created DESC')
  return respond(request, user, 'list', {'races': races})

def listclub(request):
  """Request / -- show all clubs."""

  user = users.GetCurrentUser()
  objects = db.GqlQuery('SELECT * FROM Club ORDER BY created DESC')
  return respond(request, user, 'listclub', {'clubs': objects})

def listclubentries(request, club_id):
  """Request / -- show all entries for a club."""

  user = users.GetCurrentUser()
  if user is None:
    return respond(request, user, 'message', {'msg':'You must be signed in to perform this action'})

  club = None
  if club_id:
    club = Club.get(db.Key.from_path(Club.kind(), int(club_id)))
    if club is None:
      return respond(request, user, 'message', {'msg':'No club exists with that key (%r)' % club_id})
    if club.racedirector != user and not users.IsCurrentUserAdmin():
                return respond(request, user, 'message', {'msg':'You are not the owner of this club'})

  entries = db.GqlQuery('SELECT * FROM ClubEntry WHERE clubid = :1 ORDER BY created DESC', int(club_id))
  return respond(request, user, 'listclubentries', {'entries': entries, 'club':club})

def edit(request, race_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  #q = db.GqlQuery("SELECT * FROM Race")
  #results = q.fetch(10)
  #for result in results:
	#result.delete()

  user = users.GetCurrentUser()
  if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit a race')
    return respond(request, user, 'message', {'msg':'You must be signed in to add or edit a race'})

  race = None
  if race_id:
    race = Race.get(db.Key.from_path(Race.kind(), int(race_id)))
    if race is None:
      #return http.HttpResponseForbidden('No race exists with that key (%r)' % race_id)
      return respond(request, user, 'message', {'msg':'No race exists with that key (%r)' % race_id})

    if race.racedirector != user:
		#return http.HttpResponseForbidden('You are not the owner of this race')
                return respond(request, user, 'message', {'msg':'You are not the owner of this race'})

  form = RaceForm(data=request.POST or None, instance=race)

  if not request.POST:
    return respond(request, user, 'race', {'form': form, 'race': race})

  errors = form.errors
  if not errors:
    try:
      race = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
    return respond(request, user, 'race', {'form': form, 'race': race})

  if not race.racedirector:
    race.racedirector = user
  race.ip = request.META["REMOTE_ADDR"]
  race.put()

  return http.HttpResponseRedirect('/')

def new(request):
  """Create an entry.  GET shows a blank form, POST processes it."""
  return edit(request, None)

def showclubentry(request, club_entry_id):
  """show club member entry."""
  user = users.GetCurrentUser()

  clubentry = None
  if club_entry_id:
    clubentry = ClubEntry.get(db.Key.from_path(ClubEntry.kind(), int(club_entry_id)))
    if clubentry is None:
      #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
      return respond(request, user, 'message', {'msg':'No club member entry exists with that key (%r)' % club_entry_id})

  form = ClubEntryForm(data=request.POST or None, instance=clubentry)

  if not request.POST:
    return respond(request, user, 'showclubentry', {'form': form, 'clubentry': clubentry})
  #return respond(request, user, 'showclubentry', {'clubentry': clubentry})


def editclub(request, club_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()
  if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit a race')
    return respond(request, user, 'message', {'msg':'You must be signed in to add or edit a club'})

  club = None
  if club_id:
    club = Club.get(db.Key.from_path(Club.kind(), int(club_id)))
    if club is None:
      #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
      return respond(request, user, 'message', {'msg':'No club exists with that key (%r)' % club_id})
    if club.racedirector != user and not users.IsCurrentUserAdmin():
		#return http.HttpResponseForbidden('You are not the owner of this club')
                return respond(request, user, 'message', {'msg':'You are not the owner of this club'})

  form = ClubForm(data=request.POST or None, instance=club)

  if not request.POST:
    return respond(request, user, 'club', {'form': form, 'club': club})

  errors = form.errors
  if not errors:
    try:
      club = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
    return respond(request, user, 'club', {'form': form, 'club': club})

  if not club.racedirector:
    club.racedirector = user
  club.ip = request.META["REMOTE_ADDR"]
  club.put()

  return http.HttpResponseRedirect('/listclub')

def newclub(request):
  """Create an entry.  GET shows a blank form, POST processes it."""
  return editclub(request, None)

def entry(request, race_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()
  #if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit an entry')

  race = None
  if race_id:
    race = Race.get(db.Key.from_path(Race.kind(), int(race_id)))
    if race is None:
      #return http.HttpResponseForbidden('No entry exists with that key (%r)' % race_id)
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % race_id})
  entry = None

  form = EntryForm(data=request.POST or None, instance=entry)

  if not request.POST:
	  #print 'not request.POST'
	  return respond(request, user, 'entry', {'form': form, 'entry': entry, 'race':race})

  errors = form.errors
  if not errors:
    try:
      entry = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
	return respond(request, user, 'entry', {'form': form, 'entry': entry, 'race':race})

  if not entry.racedirector:
    entry.racedirector = user
  entry.ip = request.META["REMOTE_ADDR"]
  entry.raceid = int(race_id)
  entry.put()

  #return http.HttpResponseRedirect('/')
  return respond(request, user, 'payment', {'entry': entry, 'race':race})

def clubentry(request, club_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()
  #if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit an entry')

  club = None
  if club_id:
    club = Club.get(db.Key.from_path(Club.kind(), int(club_id)))
    if club is None:
      #return http.HttpResponseForbidden('No entry exists with that key (%r)' % club_id)
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % club_id})

  entry = None

  #form = ClubEntryForm(data=request.POST or None, instance=entry, initial={'email': 'xxx'})
  #form = ClubEntryForm(club, data=request.POST or None, instance=entry)
  form = ClubEntryForm(data=request.POST or None, instance=entry)
  #form = ClubEntryForm(data=request.POST or None, instance=entry, initial={'dynamic_field1': club.question1_text})
  #form = ClubEntryForm(data=request.POST or None, instance=entry, initial={'dynamic_field1': club.question1_text})

  if not request.POST:
	  #print 'not request.POST'
	  #return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club })
	  return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club, 'website':' ' } )


  errors = form.errors
  if not errors:
    try:
      entry = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)

  #if not mail.is_email_valid(entry.email):
    #return respond(request, user, 'message', {'msg':'Email is not valid %s' % entry.email})

  if not errors:
    parts = entry.email.split('@')
    if len(parts) < 2:
      return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club, 'website':' ', 'msg':'Email is not valid %s' % entry.email } )

    parts = entry.email.split('.')
    if len(parts) < 2:
      return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club, 'website':' ', 'msg':'Email is not valid %s' % entry.email } )

  if errors:
	#return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club})
	return respond(request, user, 'clubentry', {'form': form, 'entry': entry, 'club':club, 'website':' ' } )

  if not entry.racedirector:
    entry.racedirector = user
  entry.ip = request.META["REMOTE_ADDR"]
  entry.clubid = int(club_id)
  entry.put()

  #return http.HttpResponseRedirect('/')

  item = gmodel.item_t(merchant_item_id = 'id1',
  		  name             = club.name,
  		  description      = 'One year individual member price',
  		  unit_price       = gmodel.price_t(value    = club.one_year_individual_member_price,
  						    currency = 'USD'),
  		  quantity = 1)

  #return gchecky2(request, item)
  #return respond(request, user, 'clubpayment', {'entry': entry, 'club':club, 'website':' '})
  return gchecky(request, entry)

def listentries(request, race_id):
  """Request / -- show all entries for a race."""

  user = users.GetCurrentUser()
  race = None
  if race_id:
    race = Race.get(db.Key.from_path(Race.kind(), int(race_id)))
    if race is None:
      #return http.HttpResponseForbidden('No entry exists with that key (%r)' % race_id)
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % race_id})

  entries = db.GqlQuery('SELECT * FROM Entry WHERE raceid = :1 ORDER BY created DESC', int(race_id))
  #entries = db.GqlQuery('SELECT * FROM Entry ORDER BY created DESC')
  return respond(request, user, 'listentries', {'entries': entries, 'race':race})


def about(request):
    return shortcuts.render_to_response("static/about.html")

def help(request):
    return shortcuts.render_to_response("static/help.html")


def entryx(request, race_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()
  #if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit an entry')

  race = None
  if race_id:
    race = Race.get(db.Key.from_path(Race.kind(), int(race_id)))
    if race is None:
      #return http.HttpResponseForbidden('No entry exists with that key (%r)' % race_id)
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % race_id})

  entry = None

  form = EntryForm(data=request.POST or None, instance=entry)

  if not request.POST:
	  #print 'not request.POST'
	  return respond(request, user, 'entryx', {'form': form, 'entry': entry, 'race':race})

  errors = form.errors
  if not errors:
    try:
      entry = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
	return respond(request, user, 'entryx', {'form': form, 'entry': entry, 'race':race})

  if not entry.racedirector:
    entry.racedirector = user
  entry.ip = request.META["REMOTE_ADDR"]
  entry.raceid = int(race_id)

  # call checkout procedure
  
  url = 'http://www.google.com'
  payload = 'foo=bar'
  result = urlfetch.fetch(url, payload) 


  #print result
  print result.content
  entry.put()

  return http.HttpResponseRedirect('/')
  #return respond(request, user, 'payment', {'entry': entry, 'race':race})

def delete(request, race_id):

  if users.IsCurrentUserAdmin():
    user = users.GetCurrentUser()
    if user is None:
      #return http.HttpResponseForbidden('You must be signed in to perform this operation.')
      return respond(request, user, 'message', {'msg':'You must be signed in to perform this operation.'})
  
    race = None
    if race_id:
      race = Race.get(db.Key.from_path(Race.kind(), int(race_id)))
      if race is None:
        #return http.HttpResponseForbidden('No race exists with that key (%r)' % race_id)
        return respond(request, user, 'message', {'msg':'No race exists with that key (%r)' % race_id})
      if race.racedirector != user:
  		#return http.HttpResponseForbidden('You are not the owner of this race')
                  return respond(request, user, 'message', {'msg':'You are not the owner of this race'})
      race.delete()
  return http.HttpResponseRedirect('/')

def deleteclub(request, club_id):
  user = users.GetCurrentUser()
  if user is None:
    #return http.HttpResponseForbidden('You must be signed in to perform this operation.')
    return respond(request, user, 'message', {'msg':'You must be signed in to perform this operation.'})

  club = None
  if club_id:
    club = Club.get(db.Key.from_path(Club.kind(), int(club_id)))
    if club is None:
      #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
      return respond(request, user, 'message', {'msg':'No club exists with that key (%r)' % club_id})

    #if club.racedirector != user:
                #return respond(request, user, 'message', {'msg':'You are not the owner of this club'})
    if not users.IsCurrentUserAdmin():
                #return respond(request, user, 'message', {'msg':'You are not the owner of this event.'})
                return respond(request, user, 'message', {'msg':'You are not the administrator.'})
    club.delete()
  return http.HttpResponseRedirect('/listclub')

def deleteevent(request, event_id):
  user = users.GetCurrentUser()
  if user is None:
    #return http.HttpResponseForbidden('You must be signed in to perform this operation.')
    return respond(request, user, 'message', {'msg':'You must be signed in to perform this operation.'})

  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})

    # if event.racedirector != user:
    if not users.IsCurrentUserAdmin():
                #return respond(request, user, 'message', {'msg':'You are not the owner of this event.'})
                return respond(request, user, 'message', {'msg':'You are not the administrator.'})
    event.delete()
  return http.HttpResponseRedirect('/listevent')

def deleteall(request):
  if users.IsCurrentUserAdmin():
    #q = db.GqlQuery("DROP TABLE Race")
    q = db.GqlQuery("SELECT * FROM Race")
    results = q.fetch(10)
    for result in results:
      result.delete()
  return http.HttpResponseRedirect('/')

def deleteallentry(request):
  if users.IsCurrentUserAdmin():
    #q = db.GqlQuery("DROP TABLE Race")
    q = db.GqlQuery("SELECT * FROM Entry")
    results = q.fetch(100)
    #print results
    for result in results:
      result.delete()
    q = db.GqlQuery("SELECT * FROM ClubEntry")
    results = q.fetch(100)
    #print results
    for result in results:
      result.delete()
  return http.HttpResponseRedirect('/')

def printall(request):
  #q = db.GqlQuery("DROP TABLE Race")
  user = users.GetCurrentUser()
  entries = db.GqlQuery('SELECT * FROM Entry ORDER BY created DESC')
  return respond(request, user, 'debug_listentries', {'entries': entries})

def testgchecky_simple(request):
  user = users.GetCurrentUser()
  # Create a (static) instance of Controller using your vendor ID and merchant key
  controller = Controller('250352459467836', '6N2-BsKABLaaayZ1fEBGsg', is_sandbox=True)
  
  # import Google Checkout API model
  from gchecky import model as gmodel
  
  #Create your order:
  order = gmodel.checkout_shopping_cart_t(
      shopping_cart = gmodel.shopping_cart_t(items = [
          gmodel.item_t(merchant_item_id = 'fruit_1',
                        name             = 'apple',
                        description      = 'An apple a day keeps doctors away',
                        unit_price       = gmodel.price_t(value    = .55,
                                                          currency = 'USD'),
                        quantity = 3),
          gmodel.item_t(merchant_item_id = 'fruit_2',
                        name             = 'Orange',
                        description      = 'Why every orange is orange?',
                        unit_price       = gmodel.price_t(value    = .35,
                                                          currency = 'USD'),
                        quantity = 7),
      ]),
      checkout_flow_support          = gmodel.checkout_flow_support_t(
          continue_shopping_url      = 'http://wikipedia.org/fruits/',
          request_buyer_phone_number = False))
  
  # Encode the order into XML, sign it with your merchant key and form
  # Google Checkout Button html.
  prepared = controller.prepare_order(order)
  
  # Now prepared.html contains the full google checkout button html

  #return respond(request, user, 'message', {'msg':prepared.xml})

  #print prepared.html
  res = controller.send_message(prepared, diagnose=True)
  return respond(request, user, 'message', {'msg':res})


# import Google Checkout API model
from gchecky import model as gmodel

# <?xml version="1.0" ?><create-order-recurrence-request google-order-number="124792828546509" xmlns="http://checkout.google.com/schema/2"><shopping-cart><items><item><item-description>description1</item-description><unit-price currency="USD">1.000</unit-price><item-name>name1</item-name><merchant-item-id>id1</merchant-item-id><quantity>1</quantity></item></items></shopping-cart></create-order-recurrence-request>
#
def subscription_testgchecky(request):
  #vendor_id    = '250352459467836', 
  #merchant_key = '6N2-BsKABLaaayZ1fEBGsg',
  item = gmodel.item_t(merchant_item_id = 'id1',
  		  name             = 'name1',
  		  description      = 'description1',
  		  unit_price       = gmodel.price_t(value    = 10.00,
  						    currency = 'USD'),
  		  quantity = 1)
  # bayridge food coop case, complete kristen's order
  # Danielle
  return subscription_gchecky2(request, item, '164057047104340', '949319379676887', 'LfE_9J4vjTeJ7JihVmsopg', 'Production')
  # Kristen
  #return subscription_gchecky2(request, item, '943008040002202', '949319379676887', 'LfE_9J4vjTeJ7JihVmsopg', 'Production')

  #return subscription_gchecky2(request, item, '124792828546509', '250352459467836', '6N2-BsKABLaaayZ1fEBGsg', 'Test')

def subscription_gchecky2(request, item, order_number, payment_company_id, payment_company_key, payment_mode):
  user = users.GetCurrentUser()

  order = gmodel.create_order_recurrence_request_t(
	  google_order_number = order_number,
      shopping_cart = gmodel.shopping_cart_t(items = [ 
      ]),
#       checkout_flow_support          = gmodel.checkout_flow_support_t(
#           continue_shopping_url      = 'http://move.brooklynmarathon.com',
#           request_buyer_phone_number = False)
      )
  
  # (2) append an item
  order.shopping_cart.items.append( item)
  # (3) generate HTML form that contains the encoded cart data

  html_cart = my_controller(payment_company_id, payment_company_key, payment_mode == 'Test').prepare_order(order, diagnose=True)
  # (4) pass the form to your template: {{cart.html}}
  #return dict(cart=html_cart)
  #return respond(request, user, 'message', {'msg':html_cart.xml})
  #return respond(request, user, 'ordertest', {'cart':html_cart, 'msg':html_cart.xml})
  # return respond(request, user, 'message', {'msg':order.toxml()})

  xml = html_cart.xml

  # WORKS!
  
  if payment_mode == 'Production':
    url = 'https://checkout.google.com/api/checkout/v2/request/Merchant/%s' % payment_company_id
  else:
    url = 'https://sandbox.google.com/checkout/api/checkout/v2/request/Merchant/%s' % payment_company_id

  result = urlfetch.fetch(url=url,
  			#payload=html_cart.xml,
  			payload=xml,
  			method=urlfetch.POST,
  			headers={

        'Authorization': 'Basic %s' % (b64encode('%s:%s' % (payment_company_id, payment_company_key)),),
        'Content-Type': ' application/xml; charset=UTF-8',
        'Accept': ' application/xml; charset=UTF-8'
			    })
  #debug
  #return respond(request, user, 'message', {'msg':html_cart.xml})
  #return respond(request, user, 'message', {'msg':xml})

  dom = minidom.parseString(result.content)
  error = None
  if dom.getElementsByTagName('error-message'):
    error = dom.getElementsByTagName('error-message')[0].firstChild.data
  if error:
    return respond(request, user, 'message', {'msg':error})
  else:
    if dom.getElementsByTagName('redirect-url'):
      redirecturl = dom.getElementsByTagName('redirect-url')[0].firstChild.data
      if redirecturl:
        return http.HttpResponseRedirect(redirecturl)
        #return redirect_to(request=redirecturl, url=make_back_url(request, '/digital/order/'))
    else:
      return respond(request, user, 'message', {'msg':result.content})

  #return respond(request, user, 'message', {'msg':result.content})
  #return respond(request, user, 'message', {'msg':html_cart.xml})



def testgchecky(request):
  item = gmodel.item_t(merchant_item_id = 'id1',
  		  name             = 'name1',
  		  description      = 'description1',
  		  unit_price       = gmodel.price_t(value    = 1.00,
  						    currency = 'USD'),
  		  quantity = 1)
  return gchecky2(request, item)

def gchecky2(request, item, club, item2=None, price=None, description=None, evententry=None):
# this is mixed up club can be either a club or an event.  please fix this.
  user = users.GetCurrentUser()
  # (1) construct a fresh new cart object
  #cart = gmodel.checkout_shopping_cart_t()
#   order = gmodel.checkout_shopping_cart_t( shopping_cart = gmodel.shopping_cart_t( items = [
#            gmodel.item_t(merchant_item_id = 'fruit_1',
#                          name             = 'apple',
#                          description      = 'An apple a day keeps doctors away',
#                          unit_price       = gmodel.price_t(value    = .55,
#                                                            currency = 'USD'),
#                          quantity = 3),
#       ] ) )

  order = gmodel.checkout_shopping_cart_t(
      shopping_cart = gmodel.shopping_cart_t(items = [ 
#           gmodel.item_t(merchant_item_id = 'fruit_1',
#                         name             = 'apple',
#                         description      = 'An apple a day keeps doctors away',
#                         unit_price       = gmodel.price_t(value    = .55,
#                                                           currency = 'USD'),
#                         quantity = 3),
#           gmodel.item_t(merchant_item_id = 'fruit_2',
#                         name             = 'Orange',
#                         description      = 'Why every orange is orange?',
#                         unit_price       = gmodel.price_t(value    = .35,
#                                                           currency = 'USD'),
#                         quantity = 7),
      ]),
      checkout_flow_support          = gmodel.checkout_flow_support_t(
          continue_shopping_url      = 'http://move.brooklynmarathon.com',
          request_buyer_phone_number = False))
  
  # (2) append an item
  order.shopping_cart.items.append(
#       gmodel.item_t(merchant_item_id = 'id1',
#   		  name             = 'name1',
#   		  description      = 'description1',
#   		  unit_price       = gmodel.price_t(value    = 1.00,
#   						    currency = 'USD'),
#   		  quantity = 1)
       item
      )
  if item2:
    order.shopping_cart.items.append(item2)
  # (3) generate HTML form that contains the encoded cart data

  html_cart = my_controller(club.payment_company_id, club.payment_company_key, club.payment_mode == 'Test').prepare_order(order, diagnose=True)
  #html_cart = my_controller().prepare_order(order, diagnose=False)

  # (4) pass the form to your template: {{cart.html}}
  #return dict(cart=html_cart)
  #return respond(request, user, 'message', {'msg':html_cart.xml})
  #return respond(request, user, 'ordertest', {'cart':html_cart, 'msg':html_cart.xml})
  #return respond(request, user, 'message', {'msg':order.toxml()})


  # xml = {"":'<?xml version="1.0" encoding="UTF-8"?> <checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"> <shopping-cart> <items> <item> <item-name>HelloWorld 2GB MP3 Player</item-name> <item-description>HelloWorld, the simple MP3 player</item-description> <unit-price currency="USD">159.99</unit-price> <quantity>1</quantity> </item> </items> </shopping-cart> <checkout-flow-support> <merchant-checkout-flow-support> <shipping-methods> <flat-rate-shipping name="SuperShip Ground"> <price currency="USD">9.99</price> </flat-rate-shipping> </shipping-methods> </merchant-checkout-flow-support> </checkout-flow-support> </checkout-shopping-cart>'}

  # xml = {"":html_cart.xml}

  xml = html_cart.xml

  # xml = '<?xml version="1.0" ?><checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"><shopping-cart><items><item><item-name>testtest1</item-name><item-url>http://move.brooklynmarathon.com</item-url><item-description>Member price</item-description><quantity>1</quantity><unit-price currency="USD">1.000</unit-price><digital-content><description>Thank You - contact: test@test.com tracking: event-8-21</description><display-disposition>OPTIMISTIC</display-disposition></digital-content><merchant-item-id>id1</merchant-item-id><subscription period="DAILY" type="google"><recurrent-item><item-name>testtest</item-name><quantity>1</quantity><unit-price currency="USD">1.000</unit-price><digital-content><description>Thank You - contact: test@test.com tracking: event-8-21</description><display-disposition>OPTIMISTIC</display-disposition></digital-content><item-description>Member price</item-description></recurrent-item><payments><subscription-payment times="12"><maximum-charge currency="USD">24.000</maximum-charge></subscription-payment></payments></subscription></item></items></shopping-cart><checkout-flow-support><merchant-checkout-flow-support><continue-shopping-url>http://move.brooklynmarathon.com</continue-shopping-url><request-buyer-phone-number>false</request-buyer-phone-number></merchant-checkout-flow-support></checkout-flow-support></checkout-shopping-cart>'
  #xml = {"":'<?xml version="1.0" encoding="UTF-8" ?> <checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"> <shopping-cart> <items> <item> <item-name>Subscription to My Awesome Site</item-name> <item-description>Twelve Months of Access to My Awesome Site</item-description> <unit-price currency="USD">0.00</unit-price> <quantity>1</quantity> <merchant-private-item-data> ABCDEFGHIJKLMNOPQRSTUVWXYZ </merchant-private-item-data> <subscription type="google" period ="MONTHLY"> <payments> <subscription-payment times=12> <maximum-charge currency="USD">12.00</maximum-charge> </subscription-payment> </payments> <recurrent-item> <item-name>Usage of My Awesome Website for One Month</item-name> <item-description>Your flat charge for accessing my website</item-description> <quantity>1</quantity> <unit-price currency="USD">12.00</unit-price> <digital-content> <display-disposition>OPTIMISTIC</display-disposition> <url>http://mywebsite.example.com</url> <description>Head over to the website linked below for pie!</description> </digital-content> </recurrent-item> </subscription> <digital-content> <display-disposition>OPTIMISTIC</display-disposition> <description>Congratulations! Your subscription is being set up. Feel free to log onto &amp;lt;a href="http://mywebsite.example.com"&amp;gt;mywebsite.example.com&amp;lt;/a&amp;gt; and try it out!</description> </digital-content> </item> <item> <item-name>Decoder Ring</item-name> <item-description>One-time charge for the decoder ring you (coincidentally) also ordered from me.</item-description> <unit-price currency="USD">5.00</unit-price> <quantity>1</quantity> </item> </items> </shopping-cart> </checkout-shopping-cart>'}
  # WORKS!
  #xml = '<?xml version="1.0" encoding="UTF-8" ?> <checkout-shopping-cart xmlns="http://checkout.google.com/schema/2"> <shopping-cart> <items> <item> <item-name>Subscription to My Awesome Site</item-name> <item-description>Twelve Months of Access to My Awesome Site</item-description> <unit-price currency="USD">0.00</unit-price> <quantity>1</quantity> <merchant-private-item-data> ABCDEFGHIJKLMNOPQRSTUVWXYZ </merchant-private-item-data> <subscription type="google" period ="MONTHLY"> <payments> <subscription-payment times="12"> <maximum-charge currency="USD">12.00</maximum-charge> </subscription-payment> </payments> <recurrent-item> <item-name>Usage of My Awesome Website for One Month</item-name> <item-description>Your flat charge for accessing my website</item-description> <quantity>1</quantity> <unit-price currency="USD">12.00</unit-price> <digital-content> <display-disposition>OPTIMISTIC</display-disposition> <url>http://mywebsite.example.com</url> <description>Head over to the website linked below for pie!</description> </digital-content> </recurrent-item> </subscription> <digital-content> <display-disposition>OPTIMISTIC</display-disposition> <description>Congratulations! Your subscription is being set up. Feel free to log onto &amp;lt;a href="http://mywebsite.example.com"&amp;gt;mywebsite.example.com&amp;lt;/a&amp;gt; and try it out!</description> </digital-content> </item> <item> <item-name>Decoder Ring</item-name> <item-description>One-time charge for the decoder ring you (coincidentally) also ordered from me.</item-description> <unit-price currency="USD">5.00</unit-price> <quantity>1</quantity> </item> </items> </shopping-cart> </checkout-shopping-cart>'
  #form_data = urllib.urlencode(xml)
  #url = 'https://sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/%s' % my_controller(club.payment_company_id, club.payment_company_key).vendor_id
  
  if club.payment_company == 'Google Checkout':
    if club.payment_mode == 'Production':
      url = 'https://checkout.google.com/api/checkout/v2/merchantCheckout/Merchant/%s' % club.payment_company_id
    else:
      url = 'https://sandbox.google.com/checkout/api/checkout/v2/merchantCheckout/Merchant/%s' % club.payment_company_id
  
    result = urlfetch.fetch(url=url,
    			#payload=html_cart.xml,
    			payload=xml,
    			method=urlfetch.POST,
    			headers={
  
          #'Authorization': 'Basic %s' % (b64encode('%s:%s' % (my_controller().vendor_id,
          #                                                  my_controller().merchant_key)),),
          'Authorization': 'Basic %s' % (b64encode('%s:%s' % (club.payment_company_id, club.payment_company_key)),),
          'Content-Type': ' application/xml; charset=UTF-8',
          'Accept': ' application/xml; charset=UTF-8'
  			    })
    #debug
    #return respond(request, user, 'message', {'msg':html_cart.xml})
    #return respond(request, user, 'message', {'msg':xml})
  
    dom = minidom.parseString(result.content)
    error = None
    if dom.getElementsByTagName('error-message'):
      error = dom.getElementsByTagName('error-message')[0].firstChild.data
    if error:
      return respond(request, user, 'message', {'msg':error})
    else:
      if dom.getElementsByTagName('redirect-url'):
        redirecturl = dom.getElementsByTagName('redirect-url')[0].firstChild.data
        if redirecturl:
          return http.HttpResponseRedirect(redirecturl)
          #return redirect_to(request=redirecturl, url=make_back_url(request, '/digital/order/'))
      else:
        return respond(request, user, 'message', {'msg':result.content})
  elif club.payment_company == 'Amazon':
    if club.recurring_price_per_period:
      if club.payment_mode == 'Production':
        url = 'http://checkout.brooklynmarathon.com/GET_CustomerRecurringToken'
      else:
        url = 'http://checkout-sandbox.brooklynmarathon.com/GET_CustomerRecurringToken'
    else:
      if club.payment_mode == 'Production':
        url = 'http://checkout.brooklynmarathon.com/GET_CustomerSingleUseToken'
      else:
        url = 'http://checkout-sandbox.brooklynmarathon.com/GET_CustomerSingleUseToken'

# club.email, clubentry.clubid, clubentry.key().id()

    form_fields = {
	    "recurring_times" : club.recurring_times,
	    "recurring_price_per_period" : club.recurring_price_per_period,
	    "recurring_period" : club.recurring_period,
	    "name" : club.name,
	    "date" : club.date,
	    "time" : club.time,
	    "location" : club.location,
	    "website" : club.website,
	    "return_link" : club.return_link_after_payment,
	    "email" : club.event_owner_email,
	    "eventid" : str(evententry.eventid),
	    "evententryid" : str(evententry.key().id()),
	    "content" : "content",
	    "amount" : str(price),
	    "reason" : description,
	    "rec_token" : club.payment_company_id
	  }
    logging.info('amount: %s, reason: %s payment_company_id: %s' % (str(price), description, club.payment_company_id))
    form_data = urllib.urlencode(form_fields)
    return http.HttpResponseRedirect('%s?%s' % (url, form_data))

#     result = urlfetch.fetch(url=url, payload=form_data, method=urlfetch.POST, headers={'Content-Type': 'application/x-www-form-urlencoded'})
#     if result.content:
#       #return http.HttpResponseRedirect(result.content)
#       return respond(request, user, 'message', {'msg':result.content})
#     else:
#       return respond(request, user, 'message', {'msg':result.content})



#The variable controller mentioned above is a singleton (stateless) object that holds your merchant user account information.

# import gchecky.controller.Controller

# Create your own Controller class
# class my_controller(gchecky.controller.Controller):
class my_controller(Controller):
  def __init__(self, vendorid, merchantkey, issandbox):
      Controller.__init__(
  	self,
  	#vendor_id    = '250352459467836', 
  	#merchant_key = '6N2-BsKABLaaayZ1fEBGsg',
  	vendor_id    = vendorid, 
  	merchant_key = merchantkey,
  	#is_sandbox   = True,
  	is_sandbox   = issandbox,
  	currency     = 'USD')
  # Below you would have to override notification handlers
  # for the message types you are interested in. See below.
  def handle_new_order(self, message, order_id, order, context):
          # (1) Save the new order info somewhere into your DB
          save_into_db(order_id, order)
          return gmodel.ok_t()
  def handle_order_state_change(self, message, order_id, order, context):
          # (2) Update the order info in your DB
          order = get_from_db(order_id)
          order.financial_state = message.previous_financial_order_state
	  # ...
          return gmodel.ok_t()




# def notification_receiver(request):
#     # (1) extract the xml text from the request body
#     assert(request.POST)
#     xml = request.raw_post_data
#     assert(xml)
#     # (2) Call your gchecky controller to decode the xml data and to call
#     # the respective notification message handler
#     result = my_controller().receive(xml)
# 
#       vars = request.vars ### GET/POST variables as a dictionary
#       body = request.bosy ### the body of the request
#       notification=parse_notification(vars,body)
#       if notification.is_charged: redirect('index')
#       elif notification.is_declined: redirect('error')
#       else: return notification.response

def parse( url ) :
   result = urlfetch.fetch(url)
   if result.status_code == 200:
           return minidom.parseString(result.content)

#def gchecky(request, club_id, entry_id):
# def gchecky(request, clubentry_id):
#   """checkout."""
#   user = users.GetCurrentUser()
# 
# #   club = None
# #   if club_id:
# #     club = Club.get(db.Key.from_path(ClubEntry.kind(), int(club_id)))
# #     if clubentry is None:
# #       #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
# #       return respond(request, user, 'clubpayment', {'msg':'No club exists with that key (%r)' % club_id})
# # 
# #   if not request.POST:
# #     #return respond(request, user, 'clubpayment', { 'club': club})
#   clubentry = None
#   if clubentry_id:
#     clubentry = ClubEntry.get(db.Key.from_path(ClubEntry.kind(), int(clubentry_id)))
#     if clubentry is None:
#       #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
#       return respond(request, user, 'clubpayment', {'msg':'No club entry exists with that key (%r)' % clubentry_id})
#  
#   if not request.POST:
#     #return respond(request, user, 'clubpayment', { 'club': club})
#     item = gmodel.item_t(merchant_item_id = 'id1',
#   		  name             = 'name1',
#   		  description      = 'description1',
#   		  unit_price       = gmodel.price_t(value    = 1.00,
#   						    currency = 'USD'),
#   		  quantity = 1)
#     return gchecky2(request, item)
#   #return respond(request, user, 'showclubentry', {'clubentry': clubentry})
 

def gchecky(request, clubentry):
  """checkout."""
  user = users.GetCurrentUser()
  form = ClubEntryForm(data=request.POST or None, instance=clubentry)
  #return respond(request, user, 'clubentry', {'msg':'No club entry exists (%r)' % clubentry, 'form': form, 'clubentry': clubentry})

  if clubentry is None:
    #return http.HttpResponseForbidden('No club exists with that key (%r)' % club_id)
    return respond(request, user, 'clubentry', {'msg':'No club entry exists (%r)' % clubentry, 'form': form, 'clubentry': clubentry})
 
  if request.POST:
    #return respond(request, user, 'clubpayment', { 'club': club})
    club = Club.get(db.Key.from_path(Club.kind(), int(clubentry.clubid)))
    if club:
      price = None
      if clubentry.membership_type == 'Five year individual member price':
        price = club.five_year_individual_member_price
      elif  clubentry.membership_type == 'Five year household member price':
        price = club.five_year_household_member_price
      elif  clubentry.membership_type == 'One year individual member price':
        price = club.one_year_individual_member_price
      elif  clubentry.membership_type == 'One year household member price':
        price = club.one_year_household_member_price
        

      item = gmodel.item_t(merchant_item_id = 'id1',
  		  name             = club.name,
  		  description      = clubentry.membership_type,
  		  unit_price       = gmodel.price_t(value    = 
		     #club.five_year_household_member_price,
		     price,
  						    currency = 'USD'),
		  # club.get(clubentry.membership_type),
		  # - contact: {{club.email}} tracking: club-{{entry.clubid|escape}}-{{entry.key.id|escape}}
		  digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = '%s - contact: %s tracking: club-%s-%s' % (club.brief_message_to_buyer_about_delivery, club.email, clubentry.clubid, clubentry.key().id())),
		  #digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = 'thanks'),
  		  quantity = 1)
      return gchecky2(request, item, club)
    else:
      return respond(request, user, 'clubentry', {'msg':'No club associated with: (%r)' % clubentry, 'form': form, 'clubentry': clubentry})

  #return respond(request, user, 'showclubentry', {'clubentry': clubentry})
  return respond(request, user, 'clubentry', {'msg':'Request must be via POST clubentry: (%r)' % clubentry, 'form': form, 'clubentry': clubentry})


class Event(db.Model):
  event_type = db.StringProperty(required=True,default='Event',choices=['Event', 'Race', 'Food Cooperative', 'Transportation', 'Team Race', 'Web Hosting', 'Computer Repair', 'Club Membership', 'Party'])
  event_owner_name = db.StringProperty(required=False)
  event_owner_email = db.StringProperty(required=True)
  name = db.StringProperty(required=True)
#   date = db.DateProperty(required=False,default='yyyy-mm-dd')
#   time = db.TimeProperty(required=False,default='hh:mm')
  date = db.DateProperty(required=False)
  time = db.TimeProperty(required=False)
  location = db.StringProperty(required=True)
  payment_company = db.StringProperty(required=True,default='Google Checkout',choices=['Google Checkout', 'Paypal', 'Amazon' ])
  payment_mode = db.StringProperty(required=True,default='Production',choices=['Production', 'Test' ])
  payment_company_id = db.StringProperty(required=True)
  payment_company_key = db.StringProperty(required=True)
#   early_registration_deadline_date = db.DateProperty(required=False,default='yyyy-mm-dd')
  early_registration_deadline_date = db.DateProperty(required=False)
  early_registration_member_price = db.FloatProperty(required=False)
  early_registration_nonmember_price = db.FloatProperty(required=False)
  #currency =  db.StringProperty(required=False,default='USD',choices=['USD', 'GBP' ])
  currency =  db.StringProperty(required=False,default='USD',choices=['USD'])
  member_price = db.FloatProperty(required=True)
  nonmember_price = db.FloatProperty(required=True)
  event_day_price = db.FloatProperty(required=False)
  recurring_price_per_period = db.FloatProperty(required=False)
  recurring_period = db.StringProperty(required=False,default='MONTHLY',choices=['HOURLY', 'DAILY', 'WEEKLY', 'SEMI_MONTHLY', 'MONTHLY' , 'EVERY_TWO_MONTHS', 'QUARTERLY', 'YEARLY'])
  recurring_times = db.IntegerProperty(required=False,default=12)
  recurring_price_first_charge = db.FloatProperty(required=False)
  registration_opening_date = db.DateProperty(required=False)
  registration_closing_date = db.DateProperty(required=False)
  event_limit = db.IntegerProperty(default=-1)
  # advertisement = db.StringProperty(required=False, verbose_name='Place any discount here. E.g., Buy 5 years and get 1 year free.')
  advertisement = db.StringProperty(required=False)
  website = db.LinkProperty(required=True)
  return_link_after_payment = db.LinkProperty(required=False)
  brief_description = db.StringProperty()
  full_description = db.TextProperty()
  generated_description = db.TextProperty()
  disclaimer = db.TextProperty()
  brief_message_to_buyer_about_delivery = db.StringProperty(required=True)
  waiver = db.TextProperty()
  racedirector = db.UserProperty()
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()
  #question1_type = db.StringProperty(default='Text',choices=['Text', 'Choices' ])
  #question1_text = db.StringProperty()
  #question1_choices = db.StringProperty()

class EventForm(djangoforms.ModelForm):
  def __init__(self, *args, **kwargs):
    super(EventForm, self).__init__(*args, **kwargs)
    self.fields.get("event_limit").help_text='The maximum number of entries for your event. -1 for unlimited.'
    self.fields.get("event_owner_email").help_text='Your email address'
    self.fields.get("payment_company_id").help_text='For Amazon, this is Recipient Token'
    self.fields.get("payment_company_key").help_text='For Amazon, this is Refund Token'
    self.fields.get("name").help_text='The name of your event'
    self.fields.get("advertisement").help_text='Place any discount here. E.g., Buy 5 years and get 1 year free.'
    self.fields.get("recurring_price_first_charge").help_text='The initial charge.  0 for no initial charge.'
    self.fields.get("recurring_price_per_period").help_text='Only set this for recurring charges (e.g., subscriptions, pay over time, etc.) This overrides the member price and nonmember price.'
    self.fields.get("recurring_times").help_text='The number of times that the recurring charge will occur.'

    user = users.GetCurrentUser()
    if user is None:
      self.fields.get("name").initial='please sign in.'
    else:
      q = db.GqlQuery('SELECT * FROM Event WHERE racedirector = :1 ORDER BY created DESC LIMIT 1', user)
      if q: 
        results = q.fetch(1)
        for result in results:
          self.fields.get("event_owner_name").initial=result.event_owner_name
          self.fields.get("event_owner_email").initial=result.event_owner_email
          self.fields.get("name").initial=result.name
          self.fields.get("location").initial=result.location
          self.fields.get("payment_company").initial=result.payment_company
          self.fields.get("payment_company_id").initial=result.payment_company_id
          self.fields.get("payment_company_key").initial=result.payment_company_key
          self.fields.get("payment_mode").initial=result.payment_mode
          self.fields.get("member_price").initial=result.member_price
          self.fields.get("nonmember_price").initial=result.nonmember_price
          self.fields.get("registration_opening_date").initial=result.registration_opening_date
          self.fields.get("registration_closing_date").initial=result.registration_closing_date
          self.fields.get("advertisement").initial=result.advertisement
          self.fields.get("website").initial=result.website
          self.fields.get("brief_description").initial=result.brief_description
          self.fields.get("full_description").initial=result.full_description
          self.fields.get("brief_message_to_buyer_about_delivery").initial=result.brief_message_to_buyer_about_delivery
  class Meta:
    model = Event
    exclude = ['racedirector', 'created', 'modified', 'ip']

def editevent(request, event_id):
  """Create or edit an event.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()
  if user is None:
    #return http.HttpResponseForbidden('You must be signed in to add or edit a race')
    return respond(request, user, 'message', {'msg':'You must be signed in to add or edit an event'})

  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
    if event.racedirector != user and not users.IsCurrentUserAdmin():
                return respond(request, user, 'message', {'msg':'You are not the owner of this event'})

  form = EventForm(data=request.POST or None, instance=event)

  recent=''
  try:
    q = db.GqlQuery('SELECT * FROM Event WHERE racedirector = :1 ORDER BY created DESC LIMIT 4', user)
    if q: 
      results = q.fetch(10)
      for result in results:
        #recent=recent + "|" + result.name
	recent=recent + "<br/>---<a href='#' onclick='document.getElementById(\"id_name\").value=\"" + result.name.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>") + "\"'><b>" + result.name + "</b></a>"
  	#recent=recent + "<br/>---<a href='#' onclick='document.getElementById(\"id_name\").value=\"" + result.name.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_event_owner_name\").value=\"" + result.event_owner_name.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_event_owner_email\").value=\"" + result.event_owner_email.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_location\").value=\"" + result.location.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_payment_company\").value=\"" + result.payment_company.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_payment_company_id\").value=\"" + result.payment_company_id.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_payment_company_key\").value=\"" + result.payment_company_key.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_payment_mode\").value=\"" + result.payment_mode.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_member_price\").value=\"" + str(result.member_price)   + "\"; document.getElementById(\"id_nonmember_price\").value=\"" + str(result.nonmember_price)   + "\"; document.getElementById(\"id_registration_opening_date\").value=\"" + str(result.registration_opening_date)   + "\"; document.getElementById(\"id_registration_closing_date\").value=\"" + str(result.registration_closing_date)   + "\"; document.getElementById(\"id_advertisement\").value=\"" + result.advertisement.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_website\").value=\"" + result.website.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_brief_description\").value=\"" + result.brief_description.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"; document.getElementById(\"id_full_description\").value=\"" + result.full_description.replace("'","&apos;").replace("\r\n","<br/>").replace("\"","&apos;").replace("\n","<br/>").replace("\r","<br/>")   + "\"'><b>" +  result.name + "</b></a>  - open: " + str(result.registration_opening_date) + " close: " + str(result.registration_closing_date)
  except Exception, e: 
    logging.error('Event Unexpected error: %s', e)

  if not request.POST:
    return respond(request, user, 'event', {'form': form, 'event': event, 'recent': recent})

  errors = form.errors
  if not errors:
    try:
      event = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)
  if errors:
    return respond(request, user, 'event', {'form': form, 'event': event})

  if not event.racedirector:
    event.racedirector = user
  event.ip = request.META["REMOTE_ADDR"]
  if event.recurring_price_per_period and event.recurring_times:
    event.member_price = event.recurring_price_per_period * event.recurring_times
    event.nonmember_price = 0.0
  if event.recurring_price_per_period and event.recurring_times and event.recurring_price_first_charge:
    event.member_price = event.recurring_price_per_period * event.recurring_times + event.recurring_price_first_charge
    event.nonmember_price = 0.0
  event.put()

  return http.HttpResponseRedirect('/listevent')

def newevent(request):
  """Create an entry.  GET shows a blank form, POST processes it."""
  return editevent(request, None)

def listevent(request):
  """Request / -- show all events."""

  user = users.GetCurrentUser()
  objects = db.GqlQuery('SELECT * FROM Event ORDER BY created DESC')
  return respond(request, user, 'listevent', {'events': objects})

class EventEntry(db.Model):

  membership_type = db.StringProperty(required=True,choices=[ 'Member price', 'Nonmember price'] , verbose_name='Price')
  accept_waiver = db.BooleanProperty(default=False)
  accept_waiver_participant_2 = db.BooleanProperty(default=False)
  accept_waiver_participant_3 = db.BooleanProperty(default=False)
  team_name = db.StringProperty(required=False)
  team_type = db.StringProperty(required=False,default='Mixed',choices=['Mixed', 'Male', 'Female'])
  first = db.StringProperty(required=True)
  middle = db.StringProperty(required=False)
  last = db.StringProperty(required=True)
  gender = db.StringProperty(required=True,choices=['M','F'])
  age = db.IntegerProperty(required=False,default=20,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
  birth_month = db.IntegerProperty(required=True,choices=[1,2,3,4,5,6,7,8,9,10,11,12])
  birth_day = db.IntegerProperty(required=True,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])
  birth_year = db.IntegerProperty(required=True,default=1970,choices=[
1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005
      ])
  email = db.StringProperty(required=True)
  daytime_phone_number = db.StringProperty(required=True)
  evening_phone_number = db.StringProperty(required=False)
  address_line_1 = db.TextProperty(required=True)
  address_line_2 = db.TextProperty(required=False)
  city = db.StringProperty(required=True)
  state = db.StringProperty(required=True,default='New York',choices=[
    'Alabama',       'Alaska',              'American Samoa', 'Arizona',
    'Arkansas',      'California',          'Colorado',       'Connecticut',
    'Delaware',      'District of Columbia','Florida',        'Georgia',
    'Guam',          'Hawaii',              'Idaho',          'Illinois',
    'Indiana',       'Iowa',                'Kansas',         'Kentucky',
    'Louisiana',     'Maine',               'Maryland',       'Massachusetts',
    'Michigan',      'Minnesota',           'Mississippi',    'Missouri',
    'Montana',       'Nebraska',            'Nevada',         'New Hampshire',
    'New Jersey',    'New Mexico',          'New York',       'North Carolina',
    'North Dakota',  'Ohio',                'Oklahoma',       'Oregon',
    'Pennsylvania',  'Puerto Rico',         'Rhode Island',   'South Carolina',
    'South Dakota',  'Tennessee',           'Texas',          'Utah',
    'Vermont',       'Virgin Islands',      'Virginia',       'Washington',
    'West Virginia', 'Wisconsin',           'Wyoming', 'Other'
      ])
  country = db.StringProperty(required=True)
  zipcode = db.StringProperty(required=True)

  participant2_first = db.StringProperty(required=False)
  participant2_last = db.StringProperty(required=False)
  participant2_gender = db.StringProperty(required=False,choices=['M','F'])
  participant2_age = db.IntegerProperty(required=False,default=20,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
  participant2_birth_month = db.IntegerProperty(required=False,choices=[1,2,3,4,5,6,7,8,9,10,11,12])
  participant2_birth_day = db.IntegerProperty(required=False,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])
  participant2_birth_year = db.IntegerProperty(required=False,default=1970,choices=[ 1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005 ])
  participant2_email = db.StringProperty(required=False)
  participant2_phone_number = db.StringProperty(required=False)
  participant2_address = db.TextProperty(required=False)
  participant2_city = db.StringProperty(required=False)
  participant2_state = db.StringProperty(required=False,default='New York',choices=[ 'Alabama',       'Alaska',              'American Samoa', 'Arizona', 'Arkansas',      'California',          'Colorado',       'Connecticut', 'Delaware',      'District of Columbia','Florida',        'Georgia', 'Guam',          'Hawaii',              'Idaho',          'Illinois', 'Indiana',       'Iowa',                'Kansas',         'Kentucky', 'Louisiana',     'Maine',               'Maryland',       'Massachusetts', 'Michigan',      'Minnesota',           'Mississippi',    'Missouri', 'Montana',       'Nebraska',            'Nevada',         'New Hampshire', 'New Jersey',    'New Mexico',          'New York',       'North Carolina', 'North Dakota',  'Ohio',                'Oklahoma',       'Oregon', 'Pennsylvania',  'Puerto Rico',         'Rhode Island',   'South Carolina', 'South Dakota',  'Tennessee',           'Texas',          'Utah', 'Vermont',       'Virgin Islands',      'Virginia',       'Washington', 'West Virginia', 'Wisconsin',           'Wyoming', 'Other' ])
  participant2_zipcode = db.StringProperty(required=False)

  participant3_first = db.StringProperty(required=False)
  participant3_last = db.StringProperty(required=False)
  participant3_gender = db.StringProperty(required=False,choices=['M','F'])
  participant3_age = db.IntegerProperty(required=False,default=20,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99])
  participant3_birth_month = db.IntegerProperty(required=False,choices=[1,2,3,4,5,6,7,8,9,10,11,12])
  participant3_birth_day = db.IntegerProperty(required=False,choices=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31])
  participant3_birth_year = db.IntegerProperty(required=False,default=1970,choices=[ 1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005 ])
  participant3_email = db.StringProperty(required=False)
  participant3_phone_number = db.StringProperty(required=False)
  participant3_address = db.TextProperty(required=False)
  participant3_city = db.StringProperty(required=False)
  participant3_state = db.StringProperty(required=False,default='New York',choices=[ 'Alabama',       'Alaska',              'American Samoa', 'Arizona', 'Arkansas',      'California',          'Colorado',       'Connecticut', 'Delaware',      'District of Columbia','Florida',        'Georgia', 'Guam',          'Hawaii',              'Idaho',          'Illinois', 'Indiana',       'Iowa',                'Kansas',         'Kentucky', 'Louisiana',     'Maine',               'Maryland',       'Massachusetts', 'Michigan',      'Minnesota',           'Mississippi',    'Missouri', 'Montana',       'Nebraska',            'Nevada',         'New Hampshire', 'New Jersey',    'New Mexico',          'New York',       'North Carolina', 'North Dakota',  'Ohio',                'Oklahoma',       'Oregon', 'Pennsylvania',  'Puerto Rico',         'Rhode Island',   'South Carolina', 'South Dakota',  'Tennessee',           'Texas',          'Utah', 'Vermont',       'Virgin Islands',      'Virginia',       'Washington', 'West Virginia', 'Wisconsin',           'Wyoming', 'Other' ])
  participant3_zipcode = db.StringProperty(required=False)



  how_did_you_hear_about_the_event = db.TextProperty(required=False)
  member_type = db.StringProperty(required=False,default='Runner',choices=['Runner', 'Walker', 'Cyclist'])
  shirt_size = db.StringProperty(required=False,default='Medium',choices=['Small', 'Medium', 'Large', 'XL' ])
  shirt_size_2 = db.StringProperty(required=False,default='Medium',choices=['Small', 'Medium', 'Large', 'XL' ])
  shirt_size_3 = db.StringProperty(required=False,default='Medium',choices=['Small', 'Medium', 'Large', 'XL' ])
  division = db.StringProperty(required=False,default='Open',choices=['Open', 'Clydesdale', 'Athena' ])
  racedirector = db.UserProperty()
  coupon_code = db.StringProperty()
  comments = db.TextProperty()
  checkout_id = db.StringProperty(required=False)
  created = db.DateTimeProperty(auto_now_add=True)
  modified = db.DateTimeProperty(auto_now=True)
  ip = db.StringProperty()
  eventid = db.IntegerProperty()
  ## WORKS
  #dynamic_field1 = db.StringProperty()
  ##
  #dynamic_field1 = DynamicStringProperty()
  #question1 = db.ReferenceProperty()

class EventEntryForm(djangoforms.ModelForm):
  def __init__(self, *args, **kwargs):
    super(EventEntryForm, self).__init__(*args, **kwargs)
    user = users.GetCurrentUser()
    #self.fields.get("membership_type").help_text='cost here'
    self.fields.get("accept_waiver").help_text='Check to accept'
    self.fields.get("accept_waiver_participant_2").help_text='Participant 2: Check to accept'
    self.fields.get("accept_waiver_participant_3").help_text='Participant 3: Check to accept'
  class Meta:
    model = EventEntry
    exclude = ['racedirector', 'created', 'modified', 'ip', 'eventid', 'checkout_id']

def evententry(request, event_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()

  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % event_id})

  entry = None

  # Test if the current date is within open and close registration dates.

  # import datetime
  now = datetime.date.today()
  if event.registration_opening_date:
    if now < event.registration_opening_date:
      return respond(request, user, 'message', {'msg':'Registration is not open.  Opening date is %s. Please return after the opening date.' % event.registration_opening_date, 'website':' '})
  if event.registration_closing_date:
    if now > event.registration_closing_date:
      return respond(request, user, 'message', {'msg':'Registration is closed.  Closing date was %s' % event.registration_closing_date, 'website':' '})

  count = getcountevententriespaged(int(event_id))
  remaining = 0
  #logging.info('count: %s, event_limit: %s' % (count, event.event_limit))
  if event.event_limit > -1:
    remaining = event.event_limit - count
    if count >= event.event_limit:
	return respond(request, user, 'message', {'msg':'Registration limit has been reached. Limit is %s.' % event.event_limit, 'website':' ', 'event':event})

  form = EventEntryForm(data=request.POST or None, instance=entry)

  if not request.POST:
      return respond(request, user, 'evententry', {'form': form, 'entry': entry, 'event':event, 'website':' ', 'currentcount':count, 'remaining': remaining} )


  errors = form.errors
  if not errors:
    try:
      entry = form.save(commit=False)
    except ValueError, err:
      errors['__all__'] = unicode(err)

  #if not mail.is_email_valid(entry.email):
    #return respond(request, user, 'message', {'msg':'Email is not valid %s' % entry.email})

  if not errors:
    parts = entry.email.split('@')
    if len(parts) < 2:
      return respond(request, user, 'evententry', {'form': form, 'entry': entry, 'event':event, 'website':' ', 'msg':'Email is not valid %s' % entry.email } )

    parts = entry.email.split('.')
    if len(parts) < 2:
      return respond(request, user, 'evententry', {'form': form, 'entry': entry, 'event':event, 'website':' ', 'msg':'Email is not valid %s' % entry.email } )

  #accept_waiver = entry.accept_waiver and entry.accept_waiver_participant_2 and entry.accept_waiver_participant_3
  #if errors or not (entry.accept_waiver and entry.accept_waiver_participant_2 and entry.accept_waiver_participant_3):
  #if errors or not accept_waiver:
  if errors:
	return respond(request, user, 'evententry', {'form': form, 'entry': entry, 'event':event, 'website':' ' } )
  if not (entry.accept_waiver and entry.accept_waiver_participant_2 and entry.accept_waiver_participant_3):
      return respond(request, user, 'evententry', {'msg':'You MUST accept the waiver(s)', 'form': form, 'entry': entry, 'event':event, 'website':' ' } )

  if not entry.racedirector:
    entry.racedirector = user
  entry.ip = request.META["REMOTE_ADDR"]
  entry.eventid = int(event_id)
  entry.put()

  #return http.HttpResponseRedirect('/')

  item = gmodel.item_t(merchant_item_id = 'id1',
  		  name             = event.name,
  		  description      = 'description',
  		  unit_price       = gmodel.price_t(value    = 1.00,
  						    currency = 'USD'),
  		  quantity = 1)

  return gchecky_event(request, entry)


def gchecky_event(request, evententry):
  """checkout."""
  user = users.GetCurrentUser()
  #logging.debug('gchecky_event: %s' % user)
  form = EventEntryForm(data=request.POST or None, instance=evententry)
  #return respond(request, user, 'evententry', {'msg':'No event entry exists (%r)' % evententry, 'form': form, 'evententry': evententry})

  if evententry is None:
    return respond(request, user, 'evententry', {'msg':'No event entry exists (%r)' % evententry, 'form': form, 'evententry': evententry})
 
  if request.POST:
    event = Event.get(db.Key.from_path(Event.kind(), int(evententry.eventid)))
    #logging.debug('event payment: %s' % event)
    if event:
      price = None
      if evententry.membership_type == 'Member price':
        price = event.member_price
      elif  evententry.membership_type == 'Nonmember price':
        price = event.nonmember_price
        
      times = 12
      if event.recurring_times:
        # times = event.recurring_times + 1
        times = event.recurring_times
      period = 'MONTHLY'
      if event.recurring_period:
        period = event.recurring_period
      if event.recurring_price_per_period:
        payments = gmodel.subscription_payment_t( times = times, maximum_charge = gmodel.price_t(value= event.recurring_price_per_period) )  
        subscription = gmodel.subscription_t(
          payments =  [ payments ] , period =  period, type = 'google',
          recurrent_item = gmodel.recurrent_item_t( name = event.name, description = evententry.membership_type,
              unit_price       = gmodel.price_t(value    = event.recurring_price_per_period, currency = 'USD'),
              digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = '%s - contact: %s tracking: event-%s-%s' % (event.brief_message_to_buyer_about_delivery, event.event_owner_email, evententry.eventid, evententry.key().id())),
              quantity = 1 
          )
        )

      item = gmodel.item_t(merchant_item_id = 'id1',
	          name             = event.name,
	          #name             = 'Name',
  		  description      = evententry.membership_type,
  		  unit_price       = gmodel.price_t(value    = 
		     price,
  						    currency = 'USD'),
		  digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = '%s - contact: %s tracking: event-%s-%s' % (event.brief_message_to_buyer_about_delivery, event.event_owner_email, evententry.eventid, evententry.key().id())),
		  #digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = 'thanks'),
  		  quantity = 1,


		  )
      #item.name = event.name
      item2 = None
      currency = 'USD'
      if event.currency:
        currency = event.currency
      if event.recurring_price_per_period:
        item.subscription = subscription
	item.unit_price = gmodel.price_t(value = 0, currency = 'USD')
	if event.recurring_price_first_charge and event.recurring_price_first_charge > 0:
          item2 = gmodel.item_t(merchant_item_id = 'id2',
  	          name             = event.name,
  	          #name             = 'Name',
    		  description      = evententry.membership_type,
    		  unit_price       = gmodel.price_t(value    = 
  		     event.recurring_price_first_charge,
    						    currency = 'USD'),
  		  #digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = '%s - contact: %s tracking: event-%s-%s' % (event.brief_message_to_buyer_about_delivery, event.event_owner_email, evententry.eventid, evententry.key().id())),
		  digital_content = gmodel.digital_content_t( display_disposition = 'OPTIMISTIC', description = 'Initial charge: %s %s' % (event.recurring_price_first_charge, currency)),
    		  quantity = 1,
  
  
  		  )
      #logging.debug('item: %s' % item)
      return gchecky2(request, item, event, item2, price, evententry.membership_type, evententry)
    else:
      return respond(request, user, 'evententry', {'msg':'No event associated with: (%r)' % evententry, 'form': form, 'evententry': evententry})

  return respond(request, user, 'evententry', {'msg':'Request must be via POST evententry: (%r)' % evententry, 'form': form, 'evententry': envententry})

def showevententry(request, event_entry_id):
  """show event member entry."""
  user = users.GetCurrentUser()

  evententry = None
  if event_entry_id:
    evententry = EventEntry.get(db.Key.from_path(EventEntry.kind(), int(event_entry_id)))
    if evententry is None:
      return respond(request, user, 'message', {'msg':'No event member entry exists with that key (%r)' % event_entry_id})

  form = EventEntryForm(data=request.POST or None, instance=evententry)

  if not request.POST:
    return respond(request, user, 'showevententry', {'form': form, 'evententry': evententry})

def checkoutevententrynone(request, event_entry_id):
  """update event member entry with checkout id."""
  user = users.GetCurrentUser()

  evententry = None
  if event_entry_id:
    evententry = EventEntry.get(db.Key.from_path(EventEntry.kind(), int(event_entry_id)))
    if evententry is None:
      return respond(request, user, 'message', {'msg':'No event member entry exists with that key (%r)' % event_entry_id})

  evententry.checkout_id = None
  evententry.put()

  form = EventEntryForm(data=request.POST or None, instance=evententry)

  if not request.POST:
    return respond(request, user, 'showevententry', {'form': form, 'evententry': evententry})

def amazonsettokens(request, event_id, token_id, refund_token_id):
  """update event member with tokens."""
  user = users.GetCurrentUser()

  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
    #if event.racedirector != user and not users.IsCurrentUserAdmin():
                #return respond(request, user, 'message', {'msg':'You are not the owner of this event'})

  # this is for historical reasons.  the id, key field is reused for amazon tokens
  if token_id and refund_token_id:
    event.payment_company_id = token_id
    event.payment_company_key = refund_token_id
    event.put()

  form = EventForm(data=request.POST or None, instance=event)

  if not request.POST:
    return respond(request, user, 'event', {'form': form, 'event': event})

def checkoutevententry(request, event_entry_id, checkout_id):
  """update event member entry with checkout id."""
  user = users.GetCurrentUser()

  evententry = None
  if event_entry_id:
    evententry = EventEntry.get(db.Key.from_path(EventEntry.kind(), int(event_entry_id)))
    if evententry is None:
      return respond(request, user, 'message', {'msg':'No event member entry exists with that key (%r)' % event_entry_id})

  if checkout_id:
    evententry.checkout_id = checkout_id
    evententry.put()

  form = EventEntryForm(data=request.POST or None, instance=evententry)

  if not request.POST:
    return respond(request, user, 'showevententry', {'form': form, 'evententry': evententry})

def checkoutevententryemail(request, event_entry_id, checkout_id, details):
  """update event member entry with checkout id."""
  user = users.GetCurrentUser()

  evententry = None
  if event_entry_id:
    evententry = EventEntry.get(db.Key.from_path(EventEntry.kind(), int(event_entry_id)))
    if evententry is None:
      return respond(request, user, 'message', {'msg':'No event member entry exists with that key (%r)' % event_entry_id})

  if checkout_id:
    evententry.checkout_id = checkout_id
    evententry.put()

  form = EventEntryForm(data=request.POST or None, instance=evententry)

  url = 'http://move.brooklynmarathon.com/showevententry/%s' % event_entry_id
  resultfetch = urlfetch.fetch(url)

#  logging.info('evententry: %s' % evententry)
#  logging.info('evententry.eventid: %s' % evententry.eventid)

  if evententry.eventid:
    event = Event.get(db.Key.from_path(Event.kind(), int(evententry.eventid)))
    listx = []
    listx.append(event.name) 
    listx.append(evententry.membership_type) 
    listx.append(details) 
    #listx.append(result.order_total) 
    #listx.append(result.shopping_cart_items_item_1_unit_price_currency) 
    listx.append(checkout_id) 
    liststr = "|".join(map(str, listx))
#    logging.info('event: %s' % event)
#    logging.info('event.event_owner_email: %s' % event.event_owner_email)
    mail.send_mail(sender="noreply@brooklynmarathon.com",
	              # to=toaddress,
	              to=event.event_owner_email,
		      bcc="fedex1@gmail.com",
		      subject="An order has been processed: %s" % liststr,
		      html=resultfetch.content,
		      # html='<html><body>xx</body></html>',
				                  body="""
Order has been processed

Details: 
%s
""" % url)

  if not request.POST:
    return respond(request, user, 'showevententry', {'form': form, 'evententry': evententry})

def checkoutclubentry(request, club_entry_id, checkout_id):
  """update club member entry with checkout id."""
  user = users.GetCurrentUser()

  clubentry = None
  if club_entry_id:
    clubentry = ClubEntry.get(db.Key.from_path(ClubEntry.kind(), int(club_entry_id)))
    if clubentry is None:
      return respond(request, user, 'message', {'msg':'No club member entry exists with that key (%r)' % club_entry_id})

  if checkout_id:
    clubentry.checkout_id = checkout_id
    clubentry.put()

  form = ClubEntryForm(data=request.POST or None, instance=clubentry)

  if not request.POST:
    return respond(request, user, 'showclubentry', {'form': form, 'clubentry': clubentry})


def listevententries(request, event_id):
  """Request / -- show all entries for a club."""

  user = users.GetCurrentUser()
  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
    if event.racedirector != user and not users.IsCurrentUserAdmin():
                return respond(request, user, 'message', {'msg':'You are not the owner of this event'})

  entries = db.GqlQuery('SELECT * FROM EventEntry WHERE eventid = :1 ORDER BY created DESC', int(event_id))
  return respond(request, user, 'listevententries', {'entries': entries, 'event':event})



import csv
from django.http import HttpResponse
from django.template.defaultfilters import slugify

def exportx(model):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s.csv' % slugify(model.__name__)
    writer = csv.writer(response)
    # Write headers to CSV file
    headers = []
    headers.append(model.name)
    writer.writerow(headers)
    races = model.all()
    #races.filter("author =", users.get_current_user())
    #races.order("-date")
    for race in races:
        row = []
	row.append(race.name)
	row.append('x "" x')
	row.append('"yyy yyy"')
        writer.writerow(row)

#     fields = model.local_fields
#    if VERSION >= (0, 97, None):
#      fields = model._meta.local_fields
#    else:
#      fields = model._meta.fields

#     for field in fields:
#       headers.append(field.name)
#     # Write data to CSV file
#     print model.objects.all()


#     for obj in model.all():
#       row = []
#       for field in model:
#         row.append(getattr(obj, field.name))
#         writer.writerow(row)
    # Return CSV file to browser as download
    return response

def csv1(request):
    #return export(Club)
    #return export(ClubEntry)
    return export(EventEntry)

def exportevententriesall(request, event_id):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s.csv' % ('event_entries', slugify(event_id))
    writer = csv.writer(response)
    entries = db.GqlQuery('SELECT * FROM EventEntry WHERE eventid = :1 ORDER BY created DESC', int(event_id))
    first = True
    for r in entries:
      if first:
        writer.writerow(dumprowcsvheader(r))
	first = False
      writer.writerow(dumprowcsv(r))
    return response	

def exportevententries(request, event_id):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s.csv' % ('event_entries', slugify(event_id))
    writer = csv.writer(response)
    entries = db.GqlQuery('SELECT * FROM EventEntry WHERE eventid = :1 ORDER BY created DESC', int(event_id))
    first = True
    for r in entries:
      if first:
        writer.writerow(dumprowcsvheader(r))
	first = False
      if r.checkout_id:
        writer.writerow(dumprowcsv(r))
    return response	

def exportclubentries(request, event_id):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s.csv' % ('club_entries', slugify(event_id))
    writer = csv.writer(response)
    entries = db.GqlQuery('SELECT * FROM ClubEntry WHERE clubid = :1 ORDER BY created DESC', int(event_id))
    first = True
    for r in entries:
      if first:
        writer.writerow(dumprowcsvheader(r))
	first = False
      if r.checkout_id:
        writer.writerow(dumprowcsv(r))
    return response	

def exportclubentriespaged(request, event_id):
    user = users.GetCurrentUser()
    if user is None:
      return respond(request, user, 'message', {'msg':'You must be signed in to perform this action.'})
    event = Club.get(db.Key.from_path(Club.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No club exists with that key (%r)' % event_id})
    if event.racedirector != user and not users.IsCurrentUserAdmin():
                return respond(request, user, 'message', {'msg':'You are not the owner of this club'})
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s_%s.csv' % (slugify(event.name),'paged_club_entries', slugify(event_id))
    writer = csv.writer(response)
    first = True
    entities = ClubEntry.all().filter('clubid =', int(event_id)).fetch(100)
    #entities = ClubEntry.all().fetch(100)
    while entities:
      for entity in entities:
        # Do something with entity
        if first:
          writer.writerow(dumprowcsvheader(entity))
	  first = False
        if entity.checkout_id:
          writer.writerow(dumprowcsv(entity))
      entities = ClubEntry.all().filter('clubid =', int(event_id)).filter('__key__ >', entities[-1].key()).fetch(100)
      #entities = ClubEntry.all().filter('__key__ >', entities[-1].key()).fetch(100)
    return response	

def exportevententriespaged(request, event_id):
    user = users.GetCurrentUser()
    if user is None:
      return respond(request, user, 'message', {'msg':'You must be signed in to perform this action.'})
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
    if event.racedirector != user and not users.IsCurrentUserAdmin():
                return respond(request, user, 'message', {'msg':'You are not the owner of this event'})
    
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s_%s.csv' % (slugify(event.name),'paged_event_entries', slugify(event_id))
    writer = csv.writer(response)
    first = True
    entities = EventEntry.all().filter('eventid =', int(event_id)).fetch(100)
    #entities = EventEntry.all().fetch(100)
    while entities:
      for entity in entities:
        # Do something with entity
        if first:
          writer.writerow(dumprowcsvheader(entity))
	  first = False
        if entity.checkout_id:
          writer.writerow(dumprowcsv(entity))
      entities = EventEntry.all().filter('eventid =', int(event_id)).filter('__key__ >', entities[-1].key()).fetch(100)
      #entities = EventEntry.all().filter('__key__ >', entities[-1].key()).fetch(100)
    return response	

def getcountevententriespaged(event_id):
    count = 0
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return -1 
    entities = EventEntry.all().filter('eventid =', int(event_id)).fetch(100)
    while entities:
      for entity in entities:
        # Do something with entity
        if entity.checkout_id:
          count = count + 1
      entities = EventEntry.all().filter('eventid =', int(event_id)).filter('__key__ >', entities[-1].key()).fetch(100)
    return count	


def exportclubentriesall(request, event_id):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s.csv' % ('club_entries', slugify(event_id))
    writer = csv.writer(response)
    entries = db.GqlQuery('SELECT * FROM ClubEntry WHERE clubid = :1 ORDER BY created DESC', int(event_id))
    first = True
    for r in entries:
      if first:
        writer.writerow(dumprowcsvheader(r))
	first = False
      writer.writerow(dumprowcsv(r))
    return response	

def exportevententry(request, event_entry_id):
    entry = EventEntry.get(db.Key.from_path(EventEntry.kind(), int(event_entry_id)))
    return exportrow(entry, event_entry_id, 'event_entry')

def exportclubentry(request, entry_id):
    entry = ClubEntry.get(db.Key.from_path(ClubEntry.kind(), int(entry_id)))
    return exportrow(entry, entry_id, 'club_entry')

def dumprow(r):
    import datetime
    a = {}
    for k in r.fields().keys():
        v = getattr(r, k)
        a['id'] = r.key().id()
	a['key'] = str(r.key())
        if isinstance(v, str):
            a[k] = str(v)
        elif isinstance(v, unicode):
            a[k] = unicode(v)
        elif isinstance(v, datetime.datetime):
            a[k] = v.strftime('%Y-%m-%d %H:%M:%S')
        elif isinstance(v, datetime.date):
            a[k] = v.strftime('%Y-%m-%d')
        elif isinstance(v, datetime.time):
            a[k] = v.strftime('%H:%M:%S')
        elif isinstance(v, (int, float, list)):
            a[k] = v
        else:
            a[k] = str(v)
    return [a]

def dumprowcsvheader(r):
    import datetime
    l = []
    for k in r.fields().keys():
      l.append(k) 
    return l	


def dumprowcsv(r):
    import datetime
    l = []

    for k in r.fields().keys():
        v = getattr(r, k)
        if isinstance(v, str):
            l.append( str(v) )
        elif isinstance(v, unicode):
            l.append( unicode(v) )
        elif isinstance(v, datetime.datetime):
            l.append( v.strftime('%Y-%m-%d %H:%M:%S') )
        elif isinstance(v, datetime.date):
            l.append( v.strftime('%Y-%m-%d') )
        elif isinstance(v, datetime.time):
            l.append( v.strftime('%H:%M:%S') )
        elif isinstance(v, (int, float, list)):
            l.append( v )
        else:
            l.append( str(v) )
    return l

def dumpquery(query):
    s = []
    for r in query:
        s.append(dumprow(r))
    return s 

def exportjson(model):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s.csv' % slugify(model.__name__)
    writer = csv.writer(response)
    for r in model.all():
      writer.writerow(dumprow(r))
    return response	

def export(model):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s.csv' % slugify(model.__name__)
    writer = csv.writer(response)
    for r in model.all():
      writer.writerow(dumprowcsv(r))
    return response	

def exportrow(row, id, name):
    response = HttpResponse(mimetype='text/csv')
    response['Content-Disposition'] = 'attachment; filename=%s_%s.csv' % (name, slugify(id))
    writer = csv.writer(response)
    writer.writerow(dumprowcsvheader(row))
    writer.writerow(dumprowcsv(row))
    return response	

def dumpall(model):
  response = HttpResponse(mimetype='text/csv')
  response['Content-Disposition'] = 'attachment; filename=%s.csv' % slugify(model.__name__)
  writer = csv.writer(response)
  entities = model.all().fetch(100)
  while entities:
    for entity in entities:
      # Do something with entity
      writer.writerow(dumprowcsv(entity))
    entities = model.all().filter('__key__ >', entities[-1].key()).fetch(100)
  return response	

def csv2(request):
  #return export(Club)
  return export(ClubEntry)
  #return export(EventEntry)


def TEXTexportevententriespaged(request, event_id):
#      user = users.GetCurrentUser()
#      if user is None:
#        return respond(request, user, 'message', {'msg':'You must be signed in to perform this action.'})
#      event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
#      if event is None:
#        return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
#      if event.racedirector != user and not users.IsCurrentUserAdmin():
#                  return respond(request, user, 'message', {'msg':'You are not the owner of this event'})
    
    response = HttpResponse(mimetype='text/plain')
    entities = EventEntry.all().filter('eventid =', int(event_id)).fetch(100)
    #entities = EventEntry.all().fetch(100)
    while entities:
      for entity in entities:
        # Do something with entity
        if entity.checkout_id:
          response.write('%s,' %entity.email)
      entities = EventEntry.all().filter('eventid =', int(event_id)).filter('__key__ >', entities[-1].key()).fetch(100)
      #entities = EventEntry.all().filter('__key__ >', entities[-1].key()).fetch(100)
    return response	

def REMINDERevententry(request, event_id):
  """Create or edit an entry.  GET shows a blank form, POST processes it."""

  user = users.GetCurrentUser()

  event = None
  if event_id:
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
      return respond(request, user, 'message', {'msg':'No entry exists with that key (%r)' % event_id})

  entry = None

  # Test if the current date is within open and close registration dates.

  # import datetime
  now = datetime.date.today()
  if event.registration_opening_date:
    if now < event.registration_opening_date:
      return respond(request, user, 'message', {'msg':'Registration is not open.  Opening date is %s. Please return after the opening date.' % event.registration_opening_date, 'website':' '})
  if event.registration_closing_date:
    if now > event.registration_closing_date:
      return respond(request, user, 'message', {'msg':'Registration is closed.  Closing date was %s' % event.registration_closing_date, 'website':' '})
     

  return respond(request, user, 'REMINDERevententry', { 'entry': entry, 'event':event, 'website':' ' } )




def SIMPLEexportevententriespaged(request, event_id):
    user = users.GetCurrentUser()
#      if user is None:
#        return respond(request, user, 'message', {'msg':'You must be signed in to perform this action.'})
    event = Event.get(db.Key.from_path(Event.kind(), int(event_id)))
    if event is None:
       return respond(request, user, 'message', {'msg':'No event exists with that key (%r)' % event_id})
#      if event.racedirector != user and not users.IsCurrentUserAdmin():
#                  return respond(request, user, 'message', {'msg':'You are not the owner of this event'})
    
    #entities = EventEntry.all().filter('eventid =', int(event_id)).order('-last').fetch(100)
    #entities = EventEntry.all().filter('eventid =', int(event_id)).order('-created').fetch(100)
    entities = EventEntry.all().filter('eventid =', int(event_id)).fetch(100)
    #entities = EventEntry.all().fetch(100)
    filter_entities = []
    while entities:
      for entity in entities:
        # Do something with entity
        if entity.checkout_id:
          filter_entities.append(entity)
          #response.write('%s,' %entity.email)
      entities = EventEntry.all().filter('eventid =', int(event_id)).filter('__key__ >', entities[-1].key()).fetch(100)
      #entities = EventEntry.all().filter('__key__ >', entities[-1].key()).fetch(100)
    return respond(request, user, 'simplelistevententries', { 'entries': filter_entities, 'event':event, 'website':' ' } )
